//	DataTypes.cpp : User defined data types for network communication
//
#include "dataprovider.h"

#include "gkadpingiface.h"
#include "utils/gradeutils.h"
#include "msgping.h"


using namespace gKad;
using namespace std;

DataProvider::DataProvider(IAppAPI *iApi) {
	this->iApi = iApi;

	waitEventPing = CreateEvent(NULL, false, false, NULL);
}

bool DataProvider::ConfigRead(string configFile) {
	this->configFile = configFile;

	try {
		config = new ConfigReader(this->configFile.c_str());
	}
	catch (exception& e) {
		KademliaMain::GetInstance()->WriteLog(e.what());
		return false;
	}

	return true;
}

string DataProvider::ConfigGetKey(string key) {
	char tempData[MAX_VALUE_LEN]; 
			
	config->GetKey(tempData, key.c_str());
	string result(tempData);

	return result;
}


BOOTUP_RESULT DataProvider::Bootstrap() {
	// get bootstrap node addres
	string bstrpAddr = ConfigGetKey("bootstrap_address");
	TGradeAddr destAddr;
	try {
		destAddr = GradeUtils::String2GradeAddr(&bstrpAddr);
	}
	catch (exception& e) {
		KademliaMain::GetInstance()->WriteLog(e.what());
	}

	// am I boot node?
	if (KademliaMain::GetInstance()->GetServerAddr() == destAddr) {
		return b_BOOTUP_START_SERVER;
	}

	//test if node is alive
	if (SendPing(destAddr)) {	// bootup node is alive
		 //TODO RequestId
		 //TODO RequestRoutingTable

		return b_BOOTUP_OK;
	} else {
		return b_BOOTUP_FAIL;
	}
}

bool DataProvider::SendPing(TGradeAddr dest) {
	MsgPing	*ping = new MsgPing(iApi);

	string s_timeout = ConfigGetKey("ping_timeout");
	int timeout = atoi(s_timeout.c_str());
	
	return ping->SendPing(dest, timeout);
}

//void __stdcall DataProvider::OnSendData(TAppID sender, IStream *data) {
//
//	SetEvent(waitEventPing);
	//	Triggered once the capsule returns back
	//
	// TODO diferentiate the destination applications

	//logger->LogString("OnSendData [KademliaMain.cpp] triggered.");
	//struct file_request		actRequest;
	//LARGE_INTEGER			start;
	//ULARGE_INTEGER			tmp;

	//logger->LogString("WOOHOO capsule is back");

	//start.HighPart = 0;
	//start.LowPart = 0;

	//data->Seek(start, STREAM_SEEK_SET, &tmp);
	//data->Read(&actRequest, sizeof(struct file_request), NULL);

	//if (actRequest.success) {
	//	EnterCriticalSection(&fileLock);
	//	{
	//		struct stat st;
	//		if(stat(DWNLOAD_DIR, &st) != 0) {		// directory doesn't exist - create it
	//			if (_mkdir(DWNLOAD_DIR) != 0) {
	//				logger->LogString("Could not create temporary download " \
	//					"directory. None file have been saved.");

	//				LeaveCriticalSection(&fileLock);
	//				SetEvent(waitEvent);

	//				return ;
	//			}
	//		}

	//		char fileWithPath[MAX_FILE_NAME_LEN * 2] = {'\0'};
	//		sprintf_s(fileWithPath, "%s/%s", DWNLOAD_DIR, actRequest.fileName);
	//		std::ofstream out(fileWithPath);
	//		if (out.is_open() == false) {
	//			logger->LogString("Could not save file.");

	//			LeaveCriticalSection(&fileLock);
	//			SetEvent(waitEvent);
	//		}

	//		out << actRequest.fileData;

	//		out.flush();
	//		out.close();
	//	}
	//	LeaveCriticalSection(&fileLock);
	//}
	//else {
	//	logger->LogString("File have not been found.");
	//}

	//SetEvent(waitEvent);
//}




